package by.yakusekmaxim.bookgid.dataaccess.impl;
import java.util.List;

import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;

import org.hibernate.jpa.criteria.OrderImpl;
import org.springframework.stereotype.Repository;

import by.yakusekmaxim.bookgid.dataaccess.AuthorDao;
import by.yakusekmaxim.bookgid.dataaccess.util.Filter;
import by.yakusekmaxim.bookgid.datamodel.Author;

@Repository
public class AuthorDaoImpl extends AbstractDaoImpl<Long, Author> implements AuthorDao {

    protected AuthorDaoImpl() {
        super(Author.class);
    }

	@Override
	public List<Author> getAllAuthor(
			SingularAttribute<Author, ?> attribute, boolean ascending,
			int startRecord, int pageSize) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Author> criteria = cBuilder
				.createQuery(Author.class);
		Root<Author> root = criteria.from(Author.class);

		criteria.select(root);
		criteria.orderBy(new OrderImpl(root.get(attribute), ascending));

		TypedQuery<Author> query = getEm().createQuery(criteria);
		query.setFirstResult(startRecord);
		query.setMaxResults(pageSize);

		List<Author> results = query.getResultList();
		return results;
	}

	@Override
	public List<Author> getAllAuthor(
			SingularAttribute<Author, ?> attribute, boolean ascending,
			int startRecord, int pageSize, Filter<Author> filter) {
		
		SingularAttribute<Author, ?> attributeF = filter.getAttribute();
		Object valueF = filter.getValue();
		
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Author> criteria = cBuilder
				.createQuery(Author.class);
		Root<Author> root = criteria.from(Author.class);
		criteria.where(cBuilder.equal(root.get(attributeF), valueF));
		criteria.select(root);
		criteria.orderBy(new OrderImpl(root.get(attribute), ascending));

		TypedQuery<Author> query = getEm().createQuery(criteria);
		query.setFirstResult(startRecord);
		query.setMaxResults(pageSize);

		List<Author> results = query.getResultList();
		return results;
	}

	@Override
	public Long getCount() {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Long> criteria = cBuilder.createQuery(Long.class);
		Root<Author> root = criteria.from(Author.class);
		criteria.select(cBuilder.count(root));

		TypedQuery<Long> query = getEm().createQuery(criteria);
		return query.getSingleResult();
	}

	@Override
	public Long getCount(SingularAttribute<Author, ?> attribute, Object value) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Long> criteria = cBuilder.createQuery(Long.class);
		Root<Author> root = criteria.from(Author.class);
		criteria.where(cBuilder.equal(root.get(attribute), value));
		criteria.select(cBuilder.count(root));

		TypedQuery<Long> query = getEm().createQuery(criteria);
		return query.getSingleResult();
	}

	@Override
	public List<Author> getAllAuthor(SingularAttribute<Author, ?> attribute,
			Object value) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();
		
		CriteriaQuery<Author> criteria = cBuilder.createQuery(Author.class);
		Root<Author> root = criteria.from(Author.class);
		criteria.where(cBuilder.equal(root.get(attribute), value));
		criteria.select(root);
		TypedQuery<Author> query = getEm().createQuery(criteria);
		List<Author> results = query.getResultList();
		return results;
	}
	
	
}
